﻿using System;
using System.Drawing;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using COUP.Core;
using COUP.Core.Entities;

namespace COUP.Core
{
    public class Spawn : iEntity
    {
        private const string _Name = "Spawn";
        private Point _Location;
        private Dictionary<int, Monster> _Monsters;
        private MonsterTypeEntry _MonsterType;
        private Rectangle _SpawnArea;
        private Map _SpawnMap;

        public event SpawnInteractionHandler PlayerInRange;

        public int UniqueID { get; set; }
        public string Name  { get { return _Name; } }
        public Point Location { get { return _Location; } }
        public Rectangle Area { get { return _SpawnArea; } }
        public Sector CurrentSector { get; set; }

        public Spawn(MonsterTypeEntry _Target, Map _Map, Point Start, Size _Size, int _Amount)
        {
            Random Rand = new Random(Environment.TickCount);
            PlayerInRange += new SpawnInteractionHandler(ReactToPlayer);
            _Monsters = new Dictionary<int, Monster>(_Amount);
            _SpawnArea = new Rectangle(Start, _Size);
            _SpawnMap = _Map;            

            for (int x = 0; x < _Amount; x++)
            {
                int X = Rand.Next(Start.X, Start.X + _Size.Width);
                int Y = Rand.Next(Start.Y, Start.Y + _Size.Height);

                while (!_SpawnMap.CheckMove(new Point(X, Y)))
                {
                    X = Rand.Next(Start.X, Start.X + _Size.Width);
                    Y = Rand.Next(Start.Y, Start.Y + _Size.Height);
                }

                Monster Mob = new Monster(_Target, 300000 + x, X, Y);
                _Monsters.Add(Mob.UniqueID, Mob);
                _SpawnMap.Insert(Mob);
            }
        }

        public void PlayerEnteredSpawn(Character Target)
        {
            PlayerInRange.Invoke(Target);
        }

        private void ReactToPlayer(Character Player)
        {
            foreach (Monster Mob in _Monsters.Values)
            {
                if (Mob.Alive && Mob.VisibleArea.Contains(Player.Area))
                {
                    ThreadPool.QueueUserWorkItem(Mob.MoveToTarget, Player);
                }
            }
        }

        private void SpawnMobs()
        {
            for (int x = 0; x < _Monsters.Count; x++)
            {
                if (!_Monsters[x].Alive)
                {
                    _Monsters[x].Respawn();
                }
            }
        }
    }
}
